package com.promis.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class RoundImageView extends android.support.v7.widget.AppCompatImageView {
    // 图片按下的画笔
    private Paint pressPaint;
    // 图片的宽高
    private int width;
    private int height;

    // 定义 Bitmap 的默认配置
    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
    private static final int COLORDRAWABLE_DIMENSION = 1;

    // 边框颜色
    private int borderColor;
    // 边框宽度
    private int borderWidth;
    // 按下的透明度
    private int pressAlpha;
    // 按下的颜色
    private int pressColor;
    // 圆角半径
    private int borderRadius;
    
    // 图片类型（矩形，圆角矩形，椭圆，圆形）
    private boolean isCircle;

    public RoundImageView(Context context) {
        super(context);
        init(context, null);
    }

    public RoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        //初始化默认值

        // 获取控件的属性值
        if (attrs != null) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
            this.borderColor = array.getColor(R.styleable.RoundImageView_borderColor, 0xddffffff);
            this.borderWidth = array.getDimensionPixelOffset(R.styleable.RoundImageView_borderWidth, 0);
            this.pressAlpha = array.getInteger(R.styleable.RoundImageView_pressAlpha, 0x0);
            this.pressColor = array.getColor(R.styleable.RoundImageView_pressColor, borderColor);
            this.borderRadius = array.getDimensionPixelOffset(R.styleable.RoundImageView_borderRadius, 0);
            this.isCircle = getWidth() == getHeight() && getWidth() / 2 == borderRadius;
            array.recycle();
        }

        // 按下的画笔设置
        pressPaint = new Paint();
        pressPaint.setAntiAlias(true);
        pressPaint.setStyle(Paint.Style.FILL);
        pressPaint.setColor(pressColor);
        pressPaint.setAlpha(0);
        pressPaint.setFlags(Paint.ANTI_ALIAS_FLAG);

        setClickable(true);
        setDrawingCacheEnabled(true);
        setWillNotDraw(false);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        // 获取当前控件的 drawable
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        // 这里 get 回来的宽度和高度是当前控件相对应的宽度和高度（在 xml 设置）
        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        // 获取 bitmap，即传入 imageview 的 bitmap
        // Bitmap bitmap = ((BitmapDrawable) ((SquaringDrawable)
        // drawable).getCurrent()).getBitmap();
        // 这里参考赵鹏的获取 bitmap 方式，因为上边的获取会导致 Glide 加载的drawable 强转为 BitmapDrawable 出错
        Bitmap bitmap = getBitmapFromDrawable(drawable);
        drawDrawable(canvas, bitmap);

        drawPress(canvas);
        drawBorder(canvas);
    }
    
    /**
     * 实现圆角的绘制
     *
     * @param canvas
     * @param bitmap
     */
    @SuppressLint("WrongConstant")
    private void drawDrawable(Canvas canvas, Bitmap bitmap) {
        // 画笔
        Paint paint = new Paint();
        // 颜色设置
        paint.setColor(0xffffffff);
        // 抗锯齿
        paint.setAntiAlias(true);
        //Paint 的 Xfermode，PorterDuff.Mode.SRC_IN 取两层图像的交集部门, 只显示上层图像。
        PorterDuffXfermode xfermode = new PorterDuffXfermode(Mode.SRC_IN);
        // 标志
        int saveFlags = Canvas.MATRIX_SAVE_FLAG
                | Canvas.CLIP_SAVE_FLAG
                | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
                | Canvas.FULL_COLOR_LAYER_SAVE_FLAG
                | Canvas.CLIP_TO_LAYER_SAVE_FLAG;
        canvas.saveLayer(0, 0, width, height, null, saveFlags);

        if (this.isCircle) {
            // 画遮罩，画出来就是一个和空间大小相匹配的圆（这里在半径上 -1 是为了不让图片超出边框）
            canvas.drawCircle(width / 2, height / 2, width / 2 - 1, paint);
        } else {
            // 当ShapeType == 2 时 图片为圆角矩形 （这里在宽高上 -1 是为了不让图片超出边框）
            RectF rectf = new RectF(1, 1, getWidth() - 1, getHeight() - 1);
            canvas.drawRoundRect(rectf, borderRadius + 1, borderRadius + 1, paint);
        }

        paint.setXfermode(xfermode);

//        // 空间的大小 / bitmap 的大小 = bitmap 缩放的倍数
//        float scaleWidth = ((float) getWidth()) / bitmap.getWidth();
//        float scaleHeight = ((float) getHeight()) / bitmap.getHeight();

        float scale = 1.0f;
		if (isCircle) {
			// 拿到bitmap宽或高的小值
			int bSize = Math.min(bitmap.getWidth(), bitmap.getHeight());
			scale = Math.min(getMeasuredWidth(), getMeasuredHeight()) * 1.0f / bSize;
		} else {
			if (!(bitmap.getWidth() == getWidth() && bitmap.getHeight() == getHeight())) {
				// 如果图片的宽或者高与view的宽高不匹配，计算出需要缩放的比例；缩放后的图片的宽高，一定要大于我们view的宽高；所以我们这里取大值；
				scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(),
						getHeight() * 1.0f / bitmap.getHeight());
			}
		}
        
        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);

        //bitmap 缩放
        Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);

        //draw 上去
        int left = (getWidth() - bmp.getWidth()) / 2;
        int top = (getHeight() - bmp.getHeight()) / 2;
        canvas.drawBitmap(bmp, left, top, paint);
        canvas.restore();

//        if(bmp.isRecycled()==false) //如果没有回收
//            bmp.recycle();
//
//        if(bitmap.isRecycled()==false) //如果没有回收
//            bitmap.recycle();
    }
    
    /**
     * 绘制控件的按下效果
     *
     * @param canvas
     */
    private void drawPress(Canvas canvas) {
        // 这里根据类型判断绘制的效果是圆形还是矩形
        if (this.isCircle) {
            // 当ShapeType == 1 时 图片为圆形 （这里在半径上 -1 是为了不让图片超出边框）
            canvas.drawCircle(width / 2, height / 2, width / 2 - 1, pressPaint);
        } else {
            // 当ShapeType == 2 时 图片为圆角矩形 （这里在宽高上 -1 是为了不让图片超出边框）
            RectF rectF = new RectF(1, 1, width - 1, height - 1);
            canvas.drawRoundRect(rectF, borderRadius + 1, borderRadius + 1, pressPaint);
        }
    }

    /**
     * 绘制自定义控件边框
     *
     * @param canvas
     */
    private void drawBorder(Canvas canvas) {
        if (borderWidth > 0) {
            Paint paint = new Paint();
            paint.setStrokeWidth(borderWidth);
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(borderColor);
            paint.setAntiAlias(true);
            // 根据控件类型的属性去绘制圆形或者矩形
            if (this.isCircle) {
                canvas.drawCircle(width / 2, height / 2, (width - borderWidth) / 2, paint);
            } else {
                // 当ShapeType = 1 时 图片为圆角矩形
                RectF rectf = new RectF(borderWidth / 2, borderWidth / 2, getWidth() - borderWidth / 2,
                        getHeight() - borderWidth / 2);
                canvas.drawRoundRect(rectf, borderRadius, borderRadius, paint);
            }
        }
    }

    /**
     * 重写父类的 onSizeChanged 方法，检测控件宽高的变化
     *
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    /**
     * 重写 onTouchEvent 监听方法，用来监听自定义控件是否被触摸
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        switch (event.getAction()) {
//            case MotionEvent.ACTION_DOWN:
//                pressPaint.setAlpha(pressAlpha);
//                invalidate();
//                break;
//            case MotionEvent.ACTION_UP:
//                pressPaint.setAlpha(0);
//                invalidate();
//                break;
//            case MotionEvent.ACTION_MOVE:
//
//                break;
//            default:
//                pressPaint.setAlpha(0);
//                invalidate();
//                break;
//        }
        return super.onTouchEvent(event);
    }

    /**
     * 这里是参考其他开发者获取Bitmap内容的方法， 之前是因为没有考虑到 Glide 加载的图片
     * 导致drawable 类型是属于 SquaringDrawable 类型，导致强转失败
     * 这里是通过drawable不同的类型来进行获取Bitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap getBitmapFromDrawable(Drawable drawable) {
    	if (drawable instanceof BitmapDrawable) {
			BitmapDrawable bd = (BitmapDrawable) drawable;
			return bd.getBitmap();
		}
		int w = drawable.getIntrinsicWidth();
		int h = drawable.getIntrinsicHeight();
		Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, w, h);
		drawable.draw(canvas);
		return bitmap;
    }

    /**
     * 设置边框颜色
     *
     * @param borderColor
     */
    public void setBorderColor(int borderColor) {
        this.borderColor = borderColor;
        invalidate();
    }

    /**
     * 设置边框宽度
     *
     * @param borderWidth
     */
    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
    }

    /**
     * 设置图片按下颜色透明度
     *
     * @param pressAlpha
     */
    public void setPressAlpha(int pressAlpha) {
        this.pressAlpha = pressAlpha;
    }

    /**
     * 设置图片按下的颜色
     *
     * @param pressColor
     */
    public void setPressColor(int pressColor) {
        this.pressColor = pressColor;
    }

    /**
     * 设置倒角半径
     *
     * @param radius
     */
    public void setRadius(int radius) {
        this.borderRadius = radius;
        invalidate();
    }
}